#include "mesh.h"

//mesh::mesh(QObject *parent) : QObject(parent)
//{

//}

Mesh::Mesh(QVector<Vertex> vertices, QVector<unsigned int> indices, QVector<Texture> textures):
    VBO(QOpenGLBuffer::VertexBuffer),
    EBO(QOpenGLBuffer::IndexBuffer)
{
    this->initializeOpenGLFunctions();
    this->vertices = vertices;
    this->indices = indices;
    this->textures = textures;
    setupMesh();
}

Mesh::Mesh()
{

}

void Mesh::Draw(QOpenGLShaderProgram &shader)
{
    if(texture0!=NULL) {
        glActiveTexture(GL_TEXTURE0);
        texture0->bind();
        shader.setUniformValue("texture_diffuse", 0);
    }
    if(texture1!=NULL) {
        glActiveTexture(GL_TEXTURE1);
        texture1->bind();
        shader.setUniformValue("texture_specular", 1);
    }

    if(texture2!=NULL) {
        glActiveTexture(GL_TEXTURE2);
        texture2->bind();
        shader.setUniformValue("texture_height", 2);
    }

    shader.bind();
    QOpenGLVertexArrayObject::Binder bind(&VAO);
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

    glActiveTexture(GL_TEXTURE0);
}

Mesh::~Mesh(){
    VBO.destroy();
    EBO.destroy();
    VAO.destroy();
    delete texture0;
    delete texture1;
}

void Mesh::setupMesh() {

    QOpenGLVertexArrayObject::Binder bind(&VAO);
    VBO.create();
    VBO.bind();
    VBO.allocate(vertices.data(),sizeof(Vertex)*vertices.size());

    EBO.create();
    EBO.bind();
    EBO.allocate(indices.data(),sizeof(unsigned int)*indices.size());

    // vertex Positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
    glEnableVertexAttribArray(0);
    // vertex normals
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
    glEnableVertexAttribArray(1);
    // vertex texture coords
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
    glEnableVertexAttribArray(2);
//    // vertex tangent
//    glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
//    glEnableVertexAttribArray(3);
//    // vertex bitangent
//    glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent));
//    glEnableVertexAttribArray(4);

    if(textures.size()>0) {
        texture0 = new QOpenGLTexture(QImage(textures[0].path));
        texture0->setWrapMode(QOpenGLTexture::Repeat);
        texture0->setMinificationFilter(QOpenGLTexture::Nearest);
        texture0->setMagnificationFilter(QOpenGLTexture::Linear);
    }
    if(textures.size()>1) {
        texture1 = new QOpenGLTexture(QImage(textures[1].path));
        texture1->setWrapMode(QOpenGLTexture::Repeat);
        texture1->setMinificationFilter(QOpenGLTexture::Nearest);
        texture1->setMagnificationFilter(QOpenGLTexture::Linear);
    }
    if(textures.size()>2) {
        texture2 = new QOpenGLTexture(QImage(textures[2].path));
        texture2->setWrapMode(QOpenGLTexture::Repeat);
        texture2->setMinificationFilter(QOpenGLTexture::Nearest);
        texture2->setMagnificationFilter(QOpenGLTexture::Linear);
    }
}
